package com.acegear.horizon.domain.models;

import com.acegear.horizon.ApplicationContextProvider;
import com.acegear.horizon.domain.events.PostCommentCreateEvent;
import com.acegear.horizon.domain.events.PostCommentDeleteEvent;
import com.acegear.horizon.domain.events.PostEventType;
import com.acegear.horizon.domain.events.processers.EventProcessor;
import com.acegear.horizon.domain.models.constraint.ContentType;
import com.acegear.horizon.domain.models.constraint.ReportType;
import com.acegear.horizon.domain.models.jpa.ContentPart;
import com.acegear.horizon.domain.models.jpa.PostComment;
import com.acegear.horizon.domain.models.jpa.Report;
import com.acegear.horizon.domain.models.jpa.UserInfo;
import com.acegear.horizon.domain.models.vo.CommentVO;
import com.acegear.horizon.domain.repository.jpa.PostCommentRepository;
import com.acegear.horizon.domain.repository.jpa.ReportRepository;
import com.acegear.horizon.domain.repository.jpa.UserInfoRepository;
import com.acegear.horizon.domain.services.ContentPartService;
import com.acegear.horizon.domain.services.PictureService;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by wangsike on 2017/2/9.
 */
public class Comment {

    private UserInfoRepository userInfoRepository;
    private PostCommentRepository postCommentRepository;
    private ReportRepository reportRepository;
    private PostComment postComment;
    private ContentPartService contentPartService;
    private EventProcessor eventProcessor;
    private PictureService pictureService;
    private ModelFactory modelFactory;

    public Comment(PostComment postComment) {
        init();
        this.postComment = postComment;
    }

    public Comment(Long postId, Long userId, Long floor, Long replyTo, Long replyFloor, List<ContentPart> contents) {
        init();
        this.postComment = new PostComment(modelFactory.nextCommentId(),postId, userId, floor, replyTo, replyFloor, contents, false);
    }

    private void init() {
        postCommentRepository = ApplicationContextProvider.getBean(PostCommentRepository.class);

        reportRepository = ApplicationContextProvider.getBean(ReportRepository.class);

        userInfoRepository = ApplicationContextProvider.getBean(UserInfoRepository.class);

        contentPartService = ApplicationContextProvider.getBean(ContentPartService.class);

        eventProcessor = ApplicationContextProvider.getBean(EventProcessor.class);

        pictureService = ApplicationContextProvider.getBean(PictureService.class);

        modelFactory = ApplicationContextProvider.getBean(ModelFactory.class);
    }

    public CommentVO getCommentVO() {
        UserInfo userInfo = userInfoRepository.findByUserId(postComment.getUserId()).get();
        return new CommentVO(postComment.getPostId(),
                postComment.getUserId(),
                userInfo.getNickname(),
                userInfo.getAvatar(),
                postComment.getCommentId(),
                postComment.getFloor(),
                postComment.getReplyTo(),
                postComment.getReplyFloor(),
                postComment.getContents(),
                postComment.getCreateAt(),
                postComment.isDeleted());
    }

    public PostComment getPostComment() {
        return postComment;
    }

    public Long getFloor() {
        return postComment.getFloor();
    }

    public Comment save() {
        contentPartService.format(postComment.getContents());
        postComment = postCommentRepository.save(postComment);
        return this;
    }

    public Long getCommentId() {
        return postComment.getCommentId();
    }

    public Report report(Long userId) {
        Report report = new Report(ReportType.COMMENT, userId, getCommentId());
        return reportRepository.save(report);
    }


    public Boolean deleteComment() {
        postComment.setDeleted(true);
        List<ContentPart> contentParts = new ArrayList<>();
        contentParts.add(new ContentPart(ContentType.TEXT, "该评论已被主人删除", 0));
        postComment.setContents(contentParts);

        save();
        publishPostCommentDelete(PostEventType.CLIENT);
        return true;
    }

    public void deleteManageComment(String reason) {
        postComment.setDeleted(true);
        postComment.getContents().forEach((contents -> {
            switch (contents.getType()) {
                case IMAGE:
                    contents.setContent(pictureService.managementImage);
                    break;
                case TEXT:
                    contents.setContent(reason);
                    break;
            }
        }));
        save();
    }

    private void publishPostCommentDelete(PostEventType postEventType) {
        eventProcessor.publish(new PostCommentDeleteEvent(getCommentId(), postEventType, null));
    }

    public void publishPostCommentCreate(PostEventType postEventType) {
        eventProcessor.publish(new PostCommentCreateEvent(getCommentId(),
                postComment.getPostId(),
                postEventType,
                postComment.getUserId(),
                postComment.getFloor(),
                postComment.getReplyTo(),
                postComment.getReplyFloor(),
                postComment.getContents()));
    }
}
